블로그_08_RSC 적용 및 성능 개선
또 느려진다... 왜?
버그를 수정한답시고 코드를 좀 건들다가 느꼈는데, 인라인 편집 버튼이 바로 안 뜨고 한참 기다려야 나왔다.
네트워크 탭을 보니 /api/auth가 두 번씩 느리게 잡혀 있었다.
기능은 정상인데 체감 UX가 확실히 늦어졌다.
뭔 코드가 문제였는지 찾다가 그냥 단순히 해결될 문제가 아닌 것 같다고 생각했다.
마침 GPT의 코덱스 5.2 모델 업데이트로 떠들썩하길래 요걸 좀 활용해서 구조 자체를 정리해보자고 결론냈다.
GPT의 도움을 받아 정리해본 원인은 다음과 같았다.
- 레이아웃이 클라이언트에 과도하게 몰려 있었다.
- 인증 요청이 중복되어 느린 응답이 그대로 UX에 영향을 줬다.
- 파일 기반 데이터들이 매번 디스크를 훑으며 비용을 쌓고 있었다.
1. RSC 방향으로 레이아웃 재정리
App Router를 쓰는데 레이아웃 전체가 클라이언트로 고정돼 있었다.
usePathname, useRouter, 상태 스토어가 상단부터 다 끌고 올라가면서
서버 컴포넌트를 쓸 수 있는 구조가 사실상 막혀버린 상태였다.
그래서 레이아웃은 서버 컴포넌트로 되돌리고, 클라이언트가 꼭 필요한 구간만 ContentShell로 분리했다.
즉, 렌더링의 기본값을 서버로 되돌린 셈이다.
리팩토링 결과는 엄청나게 체감됐다.
- 서버에서 렌더되는 영역이 늘어났고
- 클라이언트 번들이 줄었고
- 초기 렌더 비용도 낮아졌다
바로 며칠 전에 RSC 취약점(React2Shell)으로 엄청 난리었어서 공부를 했었는데, 이걸 써야겠다는 생각을 하게 될 줄이야.
지금은 패치가 됐으니 괜찮겠지 싶었다.
2. /api/auth 중복 요청 제거
GPT가 분석한 후 알려준 가장 크리티컬한 문제였다.
여러 컴포넌트가 useAuth()를 동시에 호출하고 있었고,
각자 /api/auth를 부르면서 응답이 늦으면 버튼이 늦게 뜨는 상황이었다.
결국 모두가 각자 인증 상태를 확인하느라 더 느려지는 구조가 된 셈이다.
그래서 인증 상태는 한 번만 가져오고,
트리에는 isLoggedIn만 내려주도록 구조를 바꿨다.
이후 상세 페이지에서 편집/삭제 버튼이 즉시 뜨기 시작했다.
3. 이미지 API/렌더링도 손봄
이미지 요청이 많아지면서 작은 비용들이 누적되고 있었다.
특히 API가 매번 동기 I/O를 수행하고, 로그도 과하게 찍히고 있었다.
그래서 아래처럼 정리했다.
- 이미지 API는 동기 I/O를 비동기로 전환
- 로그는 dev 환경에서만 찍도록 제한
- 이미지 렌더에
loading="lazy",decoding="async"적용
스크롤과 상세 페이지 로딩이 조금 더 부드러워졌다.
4. 캐시 전략 정리 (성능 비용 줄이기)
페이지 로딩이 길거나, 느려지는 경우가 있었는데
문제는 ‘한 번 열어볼 때마다 전부 다시 읽는 구조’였다.
파일 트리와 검색 인덱스는 매 요청 디스크를 재귀로 훑었고,
이미지 선택 패널도 열 때마다 폴더를 다시 읽어야 했다.
읽기 비용은 캐시로 줄이고 응답 시간을 안정화했다.
- 파일 트리/검색/이미지 목록:
unstable_cache+ TTL로 서버 캐시 - 글/폴더 변경 시:
revalidateTag로 즉시 무효화
5. 편집 모드 최신성 보장
캐시를 넣으면 편집 경험이 늦어지는 문제가 생길 수 있다.
특히 /image로 이미지 목록을 불러올 때, 새 파일이 바로 안 보이면 작업 흐름이 끊긴다.
편집 모드에서는 최신성을 보장하도록 분리했다.
- 이미지 선택 패널:
fresh=1로 캐시 우회 → 새 이미지 즉시 반영 - 뷰 모드는 캐시 유지 → 일반 접근 성능 보장
6. 유지보수성까지 챙기기
캐시는 시간이 지나면 어디서 설정했는지 찾기 어려운 문제가 생긴다.
그래서 태그/TTL을 상수로 묶어 변경 지점을 하나로 통일했다.
- 캐시 태그/TTL 상수화 → 변경/추적 비용 감소
- 유지보수 문서에 동작 규칙 기록
마무리
대강 정리하면 다음 작업을 했다.
- RSC를 활용할 수 있는 구조로 되돌림
- 중복 인증 요청 제거
- 이미지 I/O 개선
- 캐시 전략 도입 + 편집 모드 최신성 보장
- 캐시 규칙/상수화로 유지보수성 향상